
#include <sstream>
#include "server.h"

#define DYH_Lock 40
#define DYH_Condition 41
#define DYH_Monitor 42
#define DYH_Response 43

BitMap *freeServerLockBmp;
BitMap *freeServerCVBmp;
BitMap *freeServerMVBmp;

ServerLock *serverLocks[MAX_LOCKS];	/* the table of locks */
ServerCV *serverConditions[MAX_CVS];	/* the table of conditions */
ServerMV *serverMonitors[MAX_MVS];		/* the table of monitors */

PacketHeader sOutPktHdr, sInPktHdr;
MailHeader sOutMailHdr, sInMailHdr;

int pendingRequestIndex =0;
int type;
int which;
char* cvName;
char* globalBuffer;

struct PendingRequest
{
	char* name;
	int type;
	int numberOfNoReplies;
	char* originalClientMsg;
	int clientMachineID;
	int clientMailboxID;
	int numberOfDYHmsgs;

	//time_t timestamp;
	//List* pendingDYHmsgs;
};
PendingRequest pendingRequests[1000];

void Server() {
	//initialize locks and bitmaps
	freeServerLockBmp = new BitMap(MAX_LOCKS);
	freeServerCVBmp = new BitMap(MAX_LOCKS);
	freeServerMVBmp = new BitMap(MAX_LOCKS);

	for(int i = 0; i < MAX_LOCKS; i++) {
		serverLocks[i] = new ServerLock();
		serverConditions[i] = new ServerCV();
		serverMonitors[i] = new ServerMV();

		serverLocks[i]->name = new char[32];
		serverLocks[i]->isDeleted = true;
		serverLocks[i]->isToBeDeleted = false;

		serverConditions[i]->name = new char[32];
		serverConditions[i]->isDeleted = true;
		serverConditions[i]->isToBeDeleted = false;
		
		serverMonitors[i]->name = new char[32];
		serverMonitors[i]->isDeleted = true;
		serverMonitors[i]->isToBeDeleted = false;
	}

	for(int i = 0;i<1000;i++)
	{
		pendingRequests[i].name = new char[2];
		pendingRequests[i].type = -1;
		pendingRequests[i].numberOfNoReplies = -1;
		pendingRequests[i].originalClientMsg = new char[2];
		pendingRequests[i].clientMachineID = -1;
		pendingRequests[i].clientMailboxID = -1;
		pendingRequests[i].numberOfDYHmsgs = -1;
	}

	while(true) {
		printf("\n\n");

		char* sWhich = new char[2];
		char* buffer = new char[MaxMailSize];
		
		//Wait for a request message
		DEBUG('n', "Server loop start\n");
		postOffice->Receive(myMachID, &sInPktHdr, &sInMailHdr, buffer);
		printf("Got \"%s\" from %d, box %d\n",buffer,sInPktHdr.from,sInMailHdr.from);

		//Parse the msg
		globalBuffer = buffer;
		stringstream ss;
		ss << buffer;
		ss >> sWhich;
		//Process the msg
		which = atoi(sWhich);
		printf("which = %i\n", which);
		
		//declare data needed in the switch statement
		stringstream sLen;
		char* name = new char[32];
		cvName = new char[32];
		int newLockPosition;
		char* cLen = new char[2];
		bool success;
		int lockSuccess;
		int cvResult;
		bool cvResultBool;
		int machNum;
		int mailNum;
		char* cType = new char[2];
		  int newMVVal;
		  int* CVResultP;
		  bool haveResult = true;

	
		if(which>=11&&which<=14)
		{
			ss >> name;
			if(doIHaveLock(name)==-1)
			{
				printf("Calling DYH lock\n");
				if(doYouHaveLock(name,which)==0)
					continue;
			}
		}
		else if(which>=15&&which<=19)
		{
			ss >> cvName;
			if(doIHaveCV(cvName)==-1)
			{
				printf("Calling DYH CV\n");
				if(doYouHaveCV(cvName,which)==0)
					continue;
			}
		}
		else if(which>=26&&which<=29)
		{
			ss >> name;
			if(doIHaveMV(name)==-1)
			{
				printf("Calling DYH MV\n");
				if(doYouHaveMV(name,which)==0)
					continue;
			}
		}

Switchtop:
		
		switch(which) {
			case SC_LockCreate:
				DEBUG('n', "Server called Lock Create\n");
				
				DEBUG('n', "Lock name is: %s\n", name);
				
				newLockPosition = LockCreate_Server(name, sInMailHdr.from);
				sLen << newLockPosition;
				cLen = (char*)sLen.str().c_str();

				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if ( !success ) {
				  printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  interrupt->Halt();
				}
				break;
			case SC_LockAcquire:
				DEBUG('n', "Server called Lock Acquire\n");

				DEBUG('n', "Lock name is: %s\n", name);
				/*sLen << lockSuccess;
				sLen >> cLen;

				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if ( !success ) {
				  printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  interrupt->Halt();
				}*/

				lockSuccess = LockAcquire_Server(name, sInMailHdr.from, sInPktHdr.from);
				
				break;
			case SC_LockRelease:
				DEBUG('n', "Server called Lock Release\n");

				DEBUG('n', "Lock name is: %s\n", name);


				lockSuccess = LockRelease_Server(name, sInMailHdr.from, sInPktHdr.from);
				
				break;
			case SC_LockDelete:
				DEBUG('n', "Server called Lock Delete\n");

				DEBUG('n', "Lock name is: %s\n", name);


				lockSuccess = LockDelete_Server(name, sInMailHdr.from, sInPktHdr.from);
				sLen << lockSuccess;
				sLen >> cLen;

				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if ( !success ) {
				  printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  interrupt->Halt();
				}
				break;

			case SC_CVCreate:
				DEBUG('n', "Server called CV Create\n");
				//ss >> name;
				DEBUG('n', "CV name is: %s\n", cvName);

				// returns -1 on a fail, 0 on an already exists, and 1 on a new create
				cvResult = CVCreate_Server(cvName, sInMailHdr.from);
				sLen << cvResult;
				cLen = (char*)sLen.str().c_str();

				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;
				printf("cLen is %s\n", cLen);

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if (!success) {
					printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
					interrupt->Halt();
				}
				break;

			case SC_Wait:
				DEBUG('n', "Server called CV Wait\n");
				DEBUG('n', "[CV Wait] CV name is: %s\n", cvName);
				ss >> name;		//fills name with the Lock name
				DEBUG('n', "[CV Wait] Lock name is: %s\n", name);
	


				// returns a 0 on a fail, a 1 on success
				cvResult = CVWait_Server(name, cvName, sInMailHdr.from, sInPktHdr.from);
				if (cvResult == 0) {	//if wait failed, don't halt the thread, that would hide the problem
					sLen << cvResult;
					sLen >> cLen;

					sOutPktHdr.to = sInPktHdr.from;
					sOutMailHdr.to = sInMailHdr.from;
					sOutMailHdr.from = myMachID;
					sOutPktHdr.from = myMachID;
					sOutMailHdr.length = strlen(cLen) + 1;

					success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
					if (!success) {
						printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
						interrupt->Halt();
					}
				}
				break;

		    case SC_Signal:
		        DEBUG('n', "Server called CV Signal\n");
				DEBUG('n', "[CV Wait] CV name is: %s\n", cvName);
				ss >> name;
				DEBUG('n', "[CV Wait] Lock name is: %s\n", name);
	

				// returns 0 on fail, 1 on success
				cvResult = CVSignal_Server(cvName, name, sInPktHdr.from);
				sLen << cvResult;
				sLen >> cLen;

				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if (!success) {
					printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
					interrupt->Halt();
				}
				break;

			case SC_Broadcast:
				DEBUG('n',"Server called CV Broadcast\n");
				ss >> cvName;
				ss >> name;
				
				ss >> cType;
				machNum = atoi(cType);

				// returns false on fail, true on success
				cvResultBool = CVBroadcast_Server(cvName, name, machNum);
				cvResult = 0;
				if (cvResultBool) {
					cvResult = 1;
				}
				sLen << cvResult;
				sLen >> cLen;

				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if (!success) {
					printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
					interrupt->Halt();
				}
				break;

			case SC_CVDelete:
				DEBUG('n', "Server called CV Delete\n");
				ss >> cvName;
				ss >> name;
				machNum = atoi(name);

				// returns false on fail, true on success
				cvResultBool = CVDelete_Server(cvName, machNum);
				cvResult = 0;
				if (cvResultBool) {
					cvResult = 1;
				}
				sLen << cvResult;
				sLen >> cLen;

				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if (!success) {
					printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
					interrupt->Halt();
				}
				break;

			case SC_MVCreate:
			  DEBUG('n', "Server called MV Create");
			  ss >> cvName; // mvName
			  ss >> name;
			  machNum = atoi(name);
			  ss >> name;
			  mailNum = atoi(name); // Array Size
			  
			  // returns 0 on fail, 1 on success.
			  cvResult = MVCreate_Server(cvName, machNum, mailNum);
			  sLen << cvResult;
			  sLen >> cLen;
			  
			  sOutPktHdr.to = sInPktHdr.from;
			  sOutMailHdr.to = sInMailHdr.from;
			  sOutMailHdr.from = myMachID;
			  sOutPktHdr.from = myMachID;
			  sOutMailHdr.length = strlen(cLen) + 1;

			  success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
			  if (!success) {
			    printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
			    interrupt->Halt();
			  }
			  break;

			case SC_MVGetValue:
			  DEBUG('n', "Server called MV Get");
			  ss >> cvName; // mvName
			  ss >> name;
			  machNum = atoi(name);
			  ss >> name;
			  mailNum = atoi(name); // Array Index
			  
			  // returns NULL on fail, an int on success
			  CVResultP = MVGet_Server(cvName, machNum, mailNum);
			  if (CVResultP == NULL) {
			    printf("Error in MV Get; no value found");
			    break;
			  }
			  sLen << CVResultP;
			  sLen >> cLen;
			  
			  sOutPktHdr.to = sInPktHdr.from;
			  sOutMailHdr.to = sInMailHdr.from;
			  sOutMailHdr.from = myMachID;
			  sOutPktHdr.from = myMachID;
			  sOutMailHdr.length = strlen(cLen) + 1;

			  success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
			  if (!success) {
			    printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
			    interrupt->Halt();
			  }
			  break;

			case SC_MVSetValue:
			  DEBUG('n', "Server called MV Get");
			  ss >> cvName; // mvName
			  ss >> name;
			  machNum = atoi(name);
			  ss >> name;
			  mailNum = atoi(name); // Array Index
			  ss >> name;
			  newMVVal = atoi(name); // New Value
			  
			  // returns 0 on fail, 1 on success
			  cvResult = MVSet_Server(cvName, machNum, mailNum, newMVVal);
			  sLen << cvResult;
			  sLen >> cLen;
			  
			  sOutPktHdr.to = sInPktHdr.from;
			  sOutMailHdr.to = sInMailHdr.from;
			  sOutMailHdr.from = myMachID;
			  sOutPktHdr.from = myMachID;
			  sOutMailHdr.length = strlen(cLen) + 1;

			  success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
			  if (!success) {
			    printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
			    interrupt->Halt();
			  }
			  break;

			case SC_MVDelete:
			  DEBUG('n', "Server called MV Get");
			  ss >> cvName; // mvName
			  
			  // returns 0 on fail, 1 on success
			  cvResult = MVDelete_Server(cvName, sInMailHdr.from);
			  sLen <<cvResult;
			  sLen >> cLen;
			  
			  sOutPktHdr.to = sInPktHdr.from;
			  sOutMailHdr.to = sInMailHdr.from;
			  sOutMailHdr.from = myMachID;
			  sOutPktHdr.from = myMachID;
			  sOutMailHdr.length = strlen(cLen) + 1;

			  success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
			  if (!success) {
			    printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
			    interrupt->Halt();
			  }
			  break;
			case DYH_Lock:
			  	DEBUG('n', "Server called DYH Lock\n");
				ss >> name;
				DEBUG('n', "Lock name is: %s\n", name);
				

				ss >> cType;
				
				if(doIHaveLock(name)==-1)
				{
					haveResult = false;
				}
				
				sLen <<DYH_Response<<" "<<name<<" "<<cType<<" "<<haveResult;
				cLen = (char*)sLen.str().c_str();
				printf("%s\n",cLen);
				
				
				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if ( !success ) {
				  printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  interrupt->Halt();
				}
				break;
			case DYH_Condition:
			  	DEBUG('n', "Server called DYH Condition\n");
				ss >> name;


				ss >> cType;
				
				if(doIHaveCV(name)==-1)
				{
					haveResult = false;
				}
				
				sLen <<DYH_Response<<" "<<name<<" "<<cType<<" "<< haveResult;
				cLen = (char*)sLen.str().c_str();
				
				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if ( !success ) {
				  printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  interrupt->Halt();
				}
				break;
			case DYH_Monitor:
			  	DEBUG('n', "Server called DYH Monitor\n");
				ss >> name;
				DEBUG('n', "Monitor name is: %s\n", name);


				ss >> cType;
				
				if(doIHaveMV(name)==-1)
				{
					haveResult = false;
				}
				
				sLen <<DYH_Response<<" "<<name<<" "<<cType<<" "<< haveResult;
				cLen = (char*)sLen.str().c_str();
				
				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = myMachID;
				sOutPktHdr.from = myMachID;
				sOutMailHdr.length = strlen(cLen) + 1;

				success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
				if ( !success ) {
				  printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  interrupt->Halt();
				}
				break;
			case DYH_Response:
				DEBUG('n', "Server called DYH Response\n");
				ss >> name;
				DEBUG('n', "Element name is: %s\n", name);
				char* cResponse = new char[2];
				char* cType = new char[2];
				bool response;
				int type;
				ss >> cType;
				type = atoi(cType);
				ss >> cResponse;
				response = atoi(cResponse);
				

				int result = DYHResponse(name,type,response);
				if (result == 1)
				{
					goto Switchtop;
				}
				if(result == -1)
				{
					continue;
				}
		}
	}
}

//returns 0 if thay are different and returns 1 if they are the same
int compareStrings(char* char1, char* char2) {
	
	//checks if either parameter is null
	if(char1[0] == NULL || char2[0] == NULL) {
		//DEBUG('n', "One of your character arrays is NULL\n");
		return -1;
	}

	int size = 0;
	//check if the strings are the same size
	for(int i = 0; i < 32; i++) {
		if(char1[i] == NULL) {
			break;
		}
		size++;
	}

	if(char2[size] == NULL) {
		if(char2[size-1] == NULL) {
			//char2 is smaller
			return 0;
		}
	}
	else {
		//char2 is bigger
		return 0;
	}

	//if you're here, the arrays are the same size
	for(int i = 0; i < size; i++) {
		if(char1[i] != char2[i]) {
			//the words are different
			return 0;
		}
	}

	//if you're here, the words are the same
	return 1;
}

int LockCreate_Server(char* lockName, int ownerMachID) {
	DEBUG('n', "machine ID = %i\n", ownerMachID);
	if(ownerMachID < 0 || ownerMachID > MAX_CLIENTS) {
		printf("Machine ID is out of bounds. Why would you do that? Passed: %i\n", ownerMachID);
		//kernelLockTableLock->Release();
		return(0);
	}

	//Check if the lock has already been made
	int lockPosition = -1;
	for(int i = 0; i < MAX_LOCKS; i++) {
		if(compareStrings(serverLocks[i]->name, lockName) == 1)
		{
			//found it
			DEBUG('n', "You asked server to create lock that already exists. Returning position in array: %i\n", i);
			return(i);
		}
	}
	/*find empty space in bitmap*/
	lockPosition = freeServerLockBmp->Find();
	
	/*if no free space for locks, then let the user know*/
	if(lockPosition == -1) {
		printf("No more free spaces. You have reached the maximum number of locks! New locks cannot be made until other locks are deleted.\n");
		//kernelLockTableLock->Release();
		return(-1);
	}
	
	/*if we found a free space, make a new lock*/
	
	printf("Making new lock named %s\nIt's position in the serverLocks is %i\n", lockName, lockPosition);
	/*no errors, so make the lock and add it to the global array of locks*/
	serverLocks[lockPosition] = new ServerLock();
	serverLocks[lockPosition]->name = lockName;
	serverLocks[lockPosition]->available = true;
	serverLocks[lockPosition]->isToBeDeleted = false;
	serverLocks[lockPosition]->isDeleted = false;
	serverLocks[lockPosition]->owner.ownerID = -1;
	serverLocks[lockPosition]->owner.mailboxNumber = -1;
	serverLocks[lockPosition]->queue = new List();

	//kernelLockTableLock->Release();
	
	/*return the int so the process can use the lock*/
	return(lockPosition);
}

int LockAcquire_Server(char *lockName, int ownerMachID, int ownerMailNum) {
	DEBUG('n', "machine ID = %i\n", ownerMachID);
	if(ownerMachID < 0 || ownerMachID > MAX_CLIENTS) {
		printf("Machine ID is out of bounds. Why would you do that? Passed: %i\n", ownerMachID);
		//kernelLockTableLock->Release();
		return(0);
	}

	int sLockPos = -1;
	//find the lock in the array
	for(int i = 0; i < MAX_LOCKS; i++) {
		if(compareStrings(serverLocks[i]->name, lockName) == 1)
		{
			//found it
			DEBUG('n', "Found lock you're acquiring! Position is: %i\n", i);
			sLockPos = i;
			break;
		}
	}
	
	//check if we didn't find the lock
	if(sLockPos == -1) {
		printf("The lock you requested does not exist.\n");
		return(0);
	}

	if(sLockPos < 0 || sLockPos > MAX_LOCKS) {
		printf("Lock is out of bounds. Passed: %i\n", sLockPos);
		//kernelLockTableLock->Release();
		return(0);
	}
	/*check if that lock has been initialized*/
	if(serverLocks[sLockPos] == NULL) {
		printf("Lock has not been initialized\n");
		return(0);
	}
	/*check if that lock has been deleted*/
	if(serverLocks[sLockPos]->isDeleted == true || serverLocks[sLockPos]->isToBeDeleted == true) {
		printf("That lock has been deleted. Zombification will not be tolerated.\n");
		//kernelLockTableLock->Release();
		return(0);
	}

	/*check if anyone owns the lock*/
	if(serverLocks[sLockPos]->owner.ownerID == -1 || serverLocks[sLockPos]->owner.mailboxNumber == -1) {
		DEBUG('n', "Nobody owns the lock you are acquiring. Making you the owner.\n");
		serverLocks[sLockPos]->owner.ownerID = ownerMachID;
		serverLocks[sLockPos]->owner.mailboxNumber = ownerMailNum;
	}
	else if(serverLocks[sLockPos]->owner.ownerID != ownerMachID || serverLocks[sLockPos]->owner.mailboxNumber != ownerMailNum) {
		printf("You are not the lock owner of lock %s\n", serverLocks[sLockPos]->name);
		return(0);
	}

	if(serverLocks[sLockPos]->available == false) {	//lock is busy, so keep client waiting until it's their turn
		DEBUG('n', "Lock is busy, waiting\n");
		Owner o;
		o.ownerID = serverLocks[sLockPos]->owner.ownerID;
		o.mailboxNumber = serverLocks[sLockPos]->owner.mailboxNumber;
		serverLocks[sLockPos]->queue->Append(&o);
		//don't have to tell it to sleep, already asleep when it sent
		return(0);
	}
	else {	//lock is available, so tell client to continue
		DEBUG('n', "Lock is not busy, continue\n");
		serverLocks[sLockPos]->available = false;

		char* cReturn = "1";

		sOutPktHdr.to = sInPktHdr.from;
		sOutMailHdr.to = sInMailHdr.from;
		sOutMailHdr.from = myMachID;
		sOutPktHdr.from = myMachID;
		sOutMailHdr.length = strlen(cReturn) + 1;

		bool sent = postOffice->Send(sOutPktHdr, sOutMailHdr, cReturn);
		if ( !sent ) {
			printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
			interrupt->Halt();
		}

		return(1);
	}
}

int LockRelease_Server(char *lockName, int ownerMachID, int ownerMailNum) {
	DEBUG('n', "machine ID = %i\n", ownerMachID);
	if(ownerMachID < 0 || ownerMachID > MAX_CLIENTS) {
		printf("Machine ID is out of bounds. Why would you do that? Passed: %i\n", ownerMachID);
		//kernelLockTableLock->Release();
		return(0);
	}

	int sLockPos = -1;
	//find the lock in the array
	for(int i = 0; i < MAX_LOCKS; i++) {
		if(compareStrings(serverLocks[i]->name, lockName) == 1)
		{
			//found it
			DEBUG('n', "Found lock you're releasing! Position is: %i\n", i);
			sLockPos = i;
			break;
		}
	}
	//check if we didn't find the lock
	if(sLockPos == -1) {
		printf("The lock you requested does not exist.\n");
		return(0);
	}

	if(sLockPos < 0 || sLockPos > MAX_LOCKS) {
		printf("Lock is out of bounds. Passed: %i\n", sLockPos);
		//kernelLockTableLock->Release();
		return(0);
	}
	/*check if that lock has been initialized*/
	if(serverLocks[sLockPos] == NULL) {
		printf("Lock has not been initialized\n");
		return(0);
	}
	/*check if you are the lock owner*/
	if(serverLocks[sLockPos]->owner.ownerID != ownerMachID || serverLocks[sLockPos]->owner.mailboxNumber != ownerMailNum) {
		printf("You are not the lock owner of lock %s\n", serverLocks[sLockPos]->name);
		return(0);
	}

	/*Delete lock if it needs to be deleted*/
	if((serverLocks[sLockPos]->isToBeDeleted == true) && (serverLocks[sLockPos]->queue->IsEmpty() == true) && (serverLocks[sLockPos]->isDeleted == false)) {
		serverLocks[sLockPos]->isDeleted = true;
		DEBUG('n', "Deleting lock\n");
		freeServerLockBmp->Clear(sLockPos);
		serverLocks[sLockPos]->name[0] = NULL;
	}


	//if there is anything in the queue, let the next owner know it has the lock
	if(serverLocks[sLockPos]->queue->IsEmpty() == false) {
		Owner* o = new Owner;
		o = (Owner*)(serverLocks[sLockPos]->queue->Remove());

		sOutPktHdr.to = o->ownerID;
		sOutMailHdr.to = o->mailboxNumber;
		sOutMailHdr.from = myMachID;
		sOutPktHdr.from = myMachID;

		stringstream ss;
		char *message;
		ss << "1 ";	//read output into stringstream
		message = (char*)ss.str().c_str();	//copy stringstream into char* array

		sOutMailHdr.length = strlen(message) + 1;

		// Send the message
		printf("This Message Is Being Called\n");
		bool success = postOffice->Send(sOutPktHdr, sOutMailHdr, message);

		if (!success) {
		  printf("Release Lock postOffice send failed. No client found.\n");
		  return -1;
		}
	}
	else {	//if there is nothing left in the waiting queue and lock doesn't need to be deleted
		serverLocks[sLockPos]->available = true;
	}

	return(1);

}

int LockDelete_Server(char *lockName, int machID, int mailNum) {
	DEBUG('n', "machine ID = %i\n", machID);
	if(machID < 0 || machID > MAX_CLIENTS) {
		printf("Machine ID is out of bounds. Why would you do that? Passed: %i\n", machID);
		//kernelLockTableLock->Release();
		return(0);
	}

	int sLockPos = -1;
	//find the lock in the array
	for(int i = 0; i < MAX_LOCKS; i++) {
		if(compareStrings(serverLocks[i]->name, lockName) == 1)
		{
			//found it
			DEBUG('n', "Found lock you're deleting! Position is: %i\n", i);
			sLockPos = i;
			break;
		}
	}

	//check if we didn't find the lock
	if(sLockPos == -1) {
		printf("The lock you requested does not exist.\n");
		return(0);
	}

	if(sLockPos < 0 || sLockPos > MAX_LOCKS) {
		printf("Lock is out of bounds. Passed: %i\n", sLockPos);
		//kernelLockTableLock->Release();
		return(0);
	}
	/*if the lock has already been deleted or marked for deletion, then do nothing*/
	if(serverLocks[sLockPos]->isDeleted == true || serverLocks[sLockPos]->isToBeDeleted == true) {
		printf("Lock has already been deleted\n");
		//kernelLockTableLock->Release();
		return(0);
	}
	if(serverLocks[sLockPos]->owner.mailboxNumber != mailNum || serverLocks[sLockPos]->owner.ownerID != machID) {
		printf("You are not the lock owner of lock %s\n", serverLocks[sLockPos]->name);
		return(0);
	}

	//mark lock for deletion
	serverLocks[sLockPos]->isToBeDeleted = true;

	return 1;
}

int CVCreate_Server(char *cvName, int machID) 
{
	//check if machine id is out of bounds
	if(machID < 0 || machID > MAX_CLIENTS) 
	{
		printf("Machine ID is out of bounds. Passed: %i\n", machID);
		return(0);
	}

	// ensure the CV is not already created
	int cvPosition = -1;
	for(int i = 0; i < MAX_CVS; i++) 
	{
		if(compareStrings(serverConditions[i]->name, cvName) == 1)
		{
			// handle if that CV already exists
			printf("You asked server to create a CV that already exists.\n");
			return(i);
		}
	}

	// handle if CV doesn't already exist (Make the CV)

	/*find empty space in bitmap*/
	cvPosition = freeServerCVBmp->Find();
	
	/*if no free space for CVs, then let the user know*/
	if(cvPosition == -1) 
	{
		printf("No more free spaces. You have reached the maximum number of condition variables! New CVs cannot be made until other CVs are deleted.\n");
		return(-1);
	}
	
	/* if we found a free space, make a new CV */
	printf("Making new CV with name %s. It's position is %i\n", cvName, cvPosition);
	/* no errors, so make the CV and add it to the global array of CVs */
	serverConditions[cvPosition] = new ServerCV();
	serverConditions[cvPosition]->name = cvName;
	serverConditions[cvPosition]->queue = new List();
	serverConditions[cvPosition]->queueSize = 0;
	serverConditions[cvPosition]->isDeleted = false;
	serverConditions[cvPosition]->isToBeDeleted = false;

	/* return 1 to signify a successful create */
	return cvPosition;
}

int CVWait_Server(char *lockName, char *cvName, int machID, int mailBoxNum) {
	//check if machine id is out of bounds
	if(machID < 0 || machID > MAX_CLIENTS) {
		printf("Machine ID is out of bounds. Why would you do that? Passed: %i\n", machID);
		return(0);
	}

	// Ensure the CV exists
	int cvIndex = -1;
	for (int i = 0; i < MAX_CVS; i++) {
		if (compareStrings(serverConditions[i]->name, cvName) == 1) {
			cvIndex = i;
			break;
		}
	}
	if (cvIndex == -1) {
		printf("The CV name, %s cannot be found.\n", cvName);
		return(0);
	}

	// Make sure lock exists
	int lockIndex = -1;
	for (int i = 0; i < MAX_LOCKS; i++) {
		if (compareStrings(serverLocks[i]->name, lockName) == 1) {
			lockIndex = i;
			break;
		}
	}
	if (lockIndex == -1) {
		printf("The lock, %s cannot be found.\n", lockName);
		return(0);
	}
	
	// Lock Validation
	if (serverConditions[cvIndex]->lock == NULL) {	//if CV has no associated lock
		DEBUG('n', "The CV's lock is NULL, tying this lock to the CV\n");
		serverConditions[cvIndex]->lock = serverLocks[lockIndex];
	}
	else {	//if the CV has an associated lock
		if(compareStrings(serverConditions[cvIndex]->lock->name, lockName) != 1) {	//if the passed lock is wrong
			printf("You are not the owner of the neccesary lock.\n");
			return(0);
		}
		// otherwise, continue
	}

	// CV Validation (it already exists)

	// CV is not deleted
	if (serverConditions[cvIndex]->isDeleted || serverConditions[cvIndex]->isToBeDeleted) {
		printf("The CV is deleted/to be deleted. Denied.\n");
		return(0);
	}
	if (serverConditions[cvIndex]->lock->isDeleted || serverConditions[cvIndex]->lock->isToBeDeleted) {
		printf("The lock is deleted/to be deleted. Denied.\n");
		return(0);
	}

	// Validation is complete. Create a new owner and append it to the waiting list.
	Owner *toAppend = new Owner;
	toAppend->ownerID = machID;
	toAppend->mailboxNumber = mailBoxNum;
	serverConditions[cvIndex]->queue->Append(toAppend);
	serverConditions[cvIndex]->queueSize += 1;
	serverConditions[cvIndex]->lock->owner.ownerID = NULL;
	serverConditions[cvIndex]->lock->owner.mailboxNumber = NULL;
	return(1);
}

int CVSignal_Server(char *cvName, char* lockName, int machID) {
	//check if machine id is out of bounds
	if(machID < 0 || machID > MAX_CLIENTS) {
		printf("Machine ID is out of bounds. Why would you do that? Passed: %i\n", machID);
		return(0);
	}

	// Ensure the CV exists
	int cvIndex = -1;
	for (int i = 0; i < MAX_CVS; i++) {
		if (compareStrings(serverConditions[i]->name, cvName) == 1) {
			cvIndex = i;
			break;
		}
	}
	if (cvIndex == -1) {
		printf("The CV name, %s cannot be found.", cvName);
		return 0;
	}
	// Lock Validation
	if (compareStrings(serverLocks[cvIndex]->name, cvName) == 1) {
		printf("You are not the owner of the neccesary lock.");
		return 0;
	}

	// CV Validation (it already exists)

	// CV is not deleted
	if (serverConditions[cvIndex]->isDeleted || serverConditions[cvIndex]->isToBeDeleted) {
		printf("The CV is deleted/to be deleted. Denied.");
		return 0;
	}

	// There is at least one person waiting.
	if (serverConditions[cvIndex]->queue->IsEmpty()) {
		printf("There is no one to wake up. Cancelling.");
		return 0;
	}

	// Validation is complete. Wake up the waiting client.
	Owner *toWake = (Owner*)serverConditions[cvIndex]->queue->Remove();

	stringstream ss;
	ss << 1;
	char *cLen = new char[2];;
	ss >> cLen;

	sOutPktHdr.to = toWake->ownerID;
	sOutMailHdr.to = toWake->mailboxNumber;
	sOutMailHdr.from = myMachID;
	sOutPktHdr.from = myMachID;
	sOutMailHdr.length = strlen(cLen);
  
	bool success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
	if ( !success ) {
		printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
		interrupt->Halt();
	}
	serverConditions[cvIndex]->queueSize -= 1;
	if (serverConditions[cvIndex]->queueSize == 0 && serverConditions[cvIndex]->isToBeDeleted) {
		serverConditions[cvIndex]->isDeleted = true;
	}

	return 1;
}

bool CVBroadcast_Server(char *cvName, char* lockName, int machID) {
  // Ensure the CV exists
  int cvIndex = -1;
  for (int i = 0; i < MAX_CVS; i++) {
    if (serverConditions[i]->name == cvName) {
      cvIndex = i;
      break;
    }
  }
  if (cvIndex == -1) {
    printf("The CV name, %s cannot be found.", cvName);
    return(false);
  }
  // Lock Validation
  if (serverConditions[cvIndex]->lock->owner.ownerID != machID) {
    printf("You are not the owner of the neccesary lock.");
    return false;
  }

  // CV Validation (it already exists)

  // Ensure the CV is not deleted
  if (serverConditions[cvIndex]->isDeleted || serverConditions[cvIndex]->isToBeDeleted) {
    printf("The CV is deleted/to be deleted. Denied.");
    return(false);
  }

  while(CVSignal_Server(cvName, lockName, machID) == 1) {
    // calls and runs Signal until no more remain in the queue.
  }
  return true;
}

bool CVDelete_Server(char *cvName, int machID) {
  // Ensure the CV exists
  int cvIndex = -1;
  for (int i = 0; i < MAX_CVS; i++) {
    if (serverConditions[i]->name == cvName) {
      cvIndex = i;
      break;
    }
  }
  if (cvIndex == -1) {
    printf("The CV name, %s cannot be found.", cvName);
    return false;
  }
  // Lock Validation
  if (serverConditions[cvIndex]->lock->owner.ownerID != machID) {
    printf("You are not the owner of the neccesary lock.");
    return false;
  }

  // Validation complete. Mark it for deletion.
  serverConditions[cvIndex]->isToBeDeleted = true;
  return true;
}

int MVCreate_Server(char *mvName, int machID, int arrSize) {
        int mvPosition = -1;
	// ensure the MV is not already created
	for(int i = 0; i < MAX_MVS; i++) {
		if(serverMonitors[i] != NULL) {
		        if(serverMonitors[i]->name == mvName) {
				printf("You asked server to create a MV that already exists. Returning position in array.\n");
				return(i);
			}
		}
	}

        /*find empty space in bitmap*/
	mvPosition = freeServerMVBmp->Find();
	
	/*if no free space for MVs, then let the user know*/
	if(mvPosition == -1) {
		printf("No more free spaces. You have reached the maximum number of monitor variables! New MVs cannot be made until other MVs are deleted.\n");
		return(mvPosition);
	}
	
	/* if we found a free space, make a new MV */
	printf("Making new MV with name %s\n. It's position is %i\n", mvName, mvPosition);
	/* no errors, so make the MV and add it to the global array of MVs */

	serverMonitors[mvPosition] = new ServerMV();
	serverMonitors[mvPosition]->name = mvName;
	serverMonitors[mvPosition]->values[arrSize];
	serverMonitors[mvPosition]->size = arrSize;
	serverMonitors[mvPosition]->isDeleted = false;
	serverMonitors[mvPosition]->isToBeDeleted = false;

	/*return the int so the process can use the mv */
	return(mvPosition);
}

int* MVGet_Server(char *mvName, int machID, int monIndex) {
  // Ensure the MV exists
  int mvIndex = -1;
  for (int i = 0; i < MAX_MVS; i++) {
    if (serverMonitors[i]->name == mvName) {
      mvIndex = i;
      break;
    }
  }
  if (mvIndex == -1) {
    printf("The MV name, %s cannot be found.", mvName);
    return(NULL);
  }

  // MV is not deleted
  if (serverMonitors[mvIndex]->isDeleted || serverConditions[mvIndex]->isToBeDeleted) {
    printf("The MV is deleted/to be deleted.");
    return(NULL);
  }

  // The mon Index is within bounds.
  if (monIndex < 0 || monIndex > serverMonitors[mvIndex]->size) {
    printf("The index for the monitor is out of bounds.");
    return(NULL);
  }

  // Validation is complete.
  return serverMonitors[mvIndex]->values[monIndex];
}

int MVSet_Server(char *mvName, int machID, int monIndex, int monValue) {
  // Ensure the MV exists
  int mvIndex = -1;
  for (int i = 0; i < MAX_MVS; i++) {
    if (serverMonitors[i]->name == mvName) {
      mvIndex = i;
      break;
    }
  }
  if (mvIndex == -1) {
    printf("The MV name, %s cannot be found.", mvName);
    return 0;
  }

  // MV is not deleted
  if (serverMonitors[mvIndex]->isDeleted || serverConditions[mvIndex]->isToBeDeleted) {
    printf("The MV is deleted/to be deleted.");
    return 0;
  }

  // The mon Index is within bounds.
  if (monIndex < 0 || monIndex > serverMonitors[mvIndex]->size) {
    printf("The index for the monitor is out of bounds.");
    return 0;
  }

  serverMonitors[mvIndex]->values[monIndex] = &monValue;
  return 1;
}

int MVDelete_Server(char *mvName, int machID) {
  int mvIndex = -1;
  for (int i = 0; i < MAX_MVS; i++) {
    if (serverMonitors[i]->name == mvName) {
      mvIndex = i;
      break;
    }
  }
  if (mvIndex == -1) {
    printf("The MV name, %s cannot be found.", mvName);
    return 0;
  }
 
   // Validation complete. Mark it for deletion.
  serverConditions[mvIndex]->isToBeDeleted = true;
  return 1;
}

int doYouHaveLock(char* elementName, int type) {
	if(numberOfServers==1)
	{
		printf("No Server to DYH\n");
		return -1;
	}

	printf("Test 1\n");
	pendingRequests[pendingRequestIndex].name = elementName;
	pendingRequests[pendingRequestIndex].type = type;
	pendingRequests[pendingRequestIndex].numberOfNoReplies = 0;
	pendingRequests[pendingRequestIndex].clientMachineID = sInPktHdr.from;
	pendingRequests[pendingRequestIndex].clientMailboxID = sInMailHdr.from;
	pendingRequests[pendingRequestIndex].originalClientMsg = globalBuffer;

	printf("Creating request name = %s, type = %i, index = %i\n",elementName,type,pendingRequestIndex);

	pendingRequestIndex= ++pendingRequestIndex%1000;
	for(int i = 0; i<numberOfServers; i++)
	{
		printf("DYH\n");
		if(i!=myMachID)
		{
			sOutPktHdr.to = i;
  			sOutMailHdr.to = i;
  			sOutMailHdr.from = myMachID;
			sOutPktHdr.from = myMachID;

  			stringstream ss;
 			char *message = new char[MaxMailSize];
  			ss << DYH_Lock<<" "<< elementName<<" "<<which;
  			message = (char*)ss.str().c_str();
  	
 			 sOutMailHdr.length = strlen(message) + 1;

  			// Send the first message
			printf("Sending Message\n");
  			bool success = postOffice->Send(sOutPktHdr, sOutMailHdr, message);
  			if ( !success ) {
						printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  		interrupt->Halt();
					}
  		}
	}
	return 0;
}

int doYouHaveCV(char* elementName, int type) {
	if(numberOfServers==1)
	{
		return -1;
	}
	pendingRequests[pendingRequestIndex].name = elementName;
	pendingRequests[pendingRequestIndex].type = type;
	pendingRequests[pendingRequestIndex].numberOfNoReplies = 0;
	pendingRequests[pendingRequestIndex].clientMachineID = sInPktHdr.from;
	pendingRequests[pendingRequestIndex].clientMailboxID = sInMailHdr.from;
	pendingRequests[pendingRequestIndex].originalClientMsg = globalBuffer;

	pendingRequestIndex= ++pendingRequestIndex%1000;

	for(int i = 0; i<numberOfServers; i++)
	{

		
			
		if(i!=myMachID)
		{
			sOutPktHdr.to = i;
  			sOutMailHdr.to = i;
  			sOutMailHdr.from = myMachID;
			sOutPktHdr.from = myMachID;

  			stringstream ss;
 			char *message = new char[MaxMailSize];
  			ss << DYH_Condition<<" " << elementName<<" "<<which;
  			message = (char*)ss.str().c_str();
  	
 			 sOutMailHdr.length = strlen(message) + 1;

  			// Send the first message
  			bool success = postOffice->Send(sOutPktHdr, sOutMailHdr, message);
			if ( !success ) {
						printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  		interrupt->Halt();
					}
  		}
	}
return 0;	

}

int doYouHaveMV(char* elementName, int type) {
	if(numberOfServers==1)
	{
		return -1;
	}

	pendingRequests[pendingRequestIndex].name = elementName;
	pendingRequests[pendingRequestIndex].type = type;
	pendingRequests[pendingRequestIndex].numberOfNoReplies = 0;
	pendingRequests[pendingRequestIndex].clientMachineID = sInPktHdr.from;
	pendingRequests[pendingRequestIndex].clientMailboxID = sInMailHdr.from;
	pendingRequests[pendingRequestIndex].originalClientMsg = globalBuffer;

	pendingRequestIndex= ++pendingRequestIndex%1000;

	for(int i = 0; i<numberOfServers; i++)
	{	
		if(i!=myMachID)
		{
			sOutPktHdr.to = i;
  			sOutMailHdr.to = i;
  			sOutMailHdr.from = myMachID;
			sOutPktHdr.from = myMachID;

  			stringstream ss;
 			char *message = new char[MaxMailSize];
  			ss << DYH_Monitor<<" " << elementName<<" "<<which;
  			message = (char*)ss.str().c_str();
  	
 			 sOutMailHdr.length = strlen(message) + 1;

  			// Send the first message
  			bool success = postOffice->Send(sOutPktHdr, sOutMailHdr, message);
			if ( !success ) {
						printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
				  		interrupt->Halt();
					}
  		}
	}
	return 0;

}

int doIHaveLock(char* elementName) {
	//search for lock in lock array
	for(int i = 0; i < MAX_LOCKS; i++) {
		if(compareStrings(serverLocks[i]->name, elementName) == 1)
		{
			//i have it
			DEBUG('n', "Server %i: I have lock %s. Returning position in array: %i\n", myMachID, elementName, i);
			return(i);
		}
	}
	
	//i don't have it
	DEBUG('n', "Server %i: I don't have lock %s\n", myMachID, elementName);
	return(-1);
}

int doIHaveCV(char* elementName) {
	//search for CV in CV array
	for(int i = 0; i < MAX_CVS; i++) {
		if(compareStrings(serverConditions[i]->name, elementName) == 1)
		{
			//i have it
			DEBUG('n', "Server %i: I have CV %s. Returning position in array: %i\n", myMachID, elementName, i);
			return(i);
		}
	}
	
	//i don't have it
	DEBUG('n', "Server %i: I don't have CV %s\n", myMachID, elementName);
	return(-1);
}

int doIHaveMV(char* elementName) {
	//search for MV in MV array
	for(int i = 0; i < MAX_MVS; i++) {
		if(compareStrings(serverMonitors[i]->name, elementName) == 1)
		{
			//i have it
			DEBUG('n', "Server %i: I have MV %s. Returning position in array: %i\n", myMachID, elementName, i);
			return(i);
		}
	}
	
	//i don't have it
	DEBUG('n', "Server %i: I don't have MV %s\n", myMachID, elementName);
	return(-1);
}

int handleDoesNotExist()
{
	stringstream sLen;
	sLen <<"-404 " << which;	//maybe pass name?
	char* cLen = new char[MaxMailSize];
	cLen = (char*)sLen.str().c_str();
				
	sOutPktHdr.to = sInPktHdr.from;
	sOutMailHdr.to = sInMailHdr.from;
	sOutMailHdr.from = myMachID;
	sOutPktHdr.from = myMachID;
	sOutMailHdr.length = strlen(cLen) + 1;

	bool success = postOffice->Send(sOutPktHdr, sOutMailHdr, cLen);
	if ( !success ) {
		printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
		interrupt->Halt();
	}

	return -1;
}

int DYHResponse(char* name, int responseType, bool response)
{
	
	for(int i = 0;i<1000; i++)
	{

		if(compareStrings(pendingRequests[i].name,name) && pendingRequests[i].type==responseType)
		{
			
			if(!response)
			{
				pendingRequests[i].numberOfNoReplies++;

				if(pendingRequests[i].numberOfNoReplies == numberOfServers-1)
				{
					if(responseType!=15)
					{
						name = name;
					}
					else
					{
						cvName = name;
					}
					
					which = responseType;
					sInPktHdr.from = pendingRequests[i].clientMachineID;
					sInMailHdr.from = pendingRequests[i].clientMachineID;
					DEBUG('n',"Response Type = %i\n",responseType);
								
					pendingRequests[i].name = "\0";
					pendingRequests[i].type = -1;
					pendingRequests[i].numberOfNoReplies = 0;
					pendingRequests[i].originalClientMsg = "\n";
					pendingRequests[i].clientMachineID = -1;
					pendingRequests[i].clientMailboxID = -1;

					for(;i<1000; i++)
					{
						if(pendingRequests[i].name==name&&pendingRequests[i].type==responseType)
						{
							pendingRequests[i].name = "\0";
							pendingRequests[i].type = -1;
							pendingRequests[i].numberOfNoReplies = 0;
							pendingRequests[i].originalClientMsg = "\n";
							pendingRequests[i].clientMachineID = -1;
							pendingRequests[i].clientMailboxID = -1;
						}
					}
				}
			}
			else
			{
				sOutPktHdr.to = sInPktHdr.from;
				sOutMailHdr.to = sInMailHdr.from;
				sOutMailHdr.from = pendingRequests[i].clientMailboxID;
				sOutPktHdr.from = pendingRequests[i].clientMachineID;
				sOutMailHdr.length = strlen(pendingRequests[i].originalClientMsg) + 1;

				printf("Forwarding Message\n");
				bool success = postOffice->Send(sOutPktHdr, sOutMailHdr, pendingRequests[i].originalClientMsg);
				if ( !success ) 
				{
							printf("The postOffice Send failed. You must not have the other Nachos running. Terminating Nachos.\n");
							interrupt->Halt();
				}
				return 0;

			}
		}
	}
	if(which == 11||which==15||which==26)
	{
		printf("Creation\n");
		return 1;
	}
	return handleDoesNotExist();
}

//based on origMsgID, determine weather to acquire (signal) or release (wait) and 
void CVLockReceiveRelease(char* lockName, char* cvName, int clientID, int origMsgID) {

}

void CVLockReceiveAcquire(char* lockName, char* cvName, int clientID, int origMsgID) {

}

int error()
{
	return -1;
}
